package com.morizhang.merchanmanager.api.utils;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

/*** 用于生成批次号，每天的个数由配置文件决定
 *
 */
@Component
public class BatchNoGenerator {
    private static void doInitialBatchNoGenerator(Environment environment) throws Exception {
        config.put("recordFile", environment.getProperty("batchnoGenerator.batchnoStartFile"));
        config.put("maxPerDay", environment.getProperty("batchnoGenerator.maxPerDay"));
        String configPoolSize = environment.getProperty("batchnoGenerator.batchPoolSize");
        if (configPoolSize != null)
            poolSize = Integer.parseInt(configPoolSize);
        poolLast = poolSize;

        String recordFilePath = config.get("recordFile");
        recordFile = new RandomAccessFile(recordFilePath, "rw");
        long lastLinePos = 0L;
        long length = recordFile.length();
        if (length > 0L) {
            long pos = length - 1;
            while (pos > 0) {
                recordFile.seek(pos);
                pos--;
                if (recordFile.readByte() == '\n') {
                    lastLinePos = pos;
                    break;
                }
            }
        }
        int bytesSize = (int) ((length - 1) - lastLinePos);
        String recordNowNum = "0";
        if (bytesSize > 0) {
            byte[] bytes = new byte[bytesSize];
            recordFile.read(bytes);
            recordNowNum = new String(bytes);
        }

        nowNum = 0;
        if (recordNowNum.length() > 0)
            nowNum = Integer.parseInt(recordNowNum.trim());

        recordToFile(nowNum + poolSize);

        Calendar calendar = Calendar.getInstance();
        nowDay = calendar.get(Calendar.DAY_OF_MONTH);
        isInit = true;
    }
    private static boolean isInit = false;
    private static HashMap<String, String> config = new HashMap<>();
    private static RandomAccessFile recordFile;
    private static int nowNum;
    private static int poolSize = 50;
    private static int poolLast;
    private static int nowDay;

    public static boolean initBatchNoGenerator(Environment environment) throws Exception {
        if (isInit)
            return false;
        else {
            doInitialBatchNoGenerator(environment);
            return true;
        }
    }

    public static String newBatchNo() throws Exception {
        if (!isInit)
            return null;

        Calendar calendar = Calendar.getInstance();
        int newNowDay = calendar.get(Calendar.DAY_OF_MONTH);
        if (nowDay != newNowDay) {
            nowNum = 0;
            poolLast = poolSize;
            nowDay = newNowDay;
            recordToFile(nowNum);
        }

        int maxPerDay = Integer.parseInt(config.get("maxPerDay"));
        if (nowNum > maxPerDay)
            return null;

        if (!(poolLast > 0)) {
            recordToFile(nowNum + poolSize);
            poolLast = poolSize;
        }

        StringBuilder batchResult = new StringBuilder();
        Date nowDate = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        batchResult.append('B');
        batchResult.append(format.format(nowDate));

        int maxPerDayLength = Integer.toString(maxPerDay).length();
        int nowNumLength = Integer.toString(nowNum).length();
        batchResult.append("0".repeat(Math.max(0, maxPerDayLength - nowNumLength)));
        batchResult.append(nowNum);
        nowNum ++;
        poolLast --;

        return batchResult.toString();
    }

    private static void recordToFile(int record) throws Exception {
        recordFile.seek(recordFile.length());
        recordFile.write(("\n" + Integer.toString(record)).getBytes());
    }
}
